# Copyright (c) 2011 Andrea Spadaccini <andrea.spadaccini@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

"""Handler for XMPP requests (i.e., application entry point)."""

__author__ = "Andrea Spadaccini"
__license__ = "GPL v3 or later"
__email__ = "andrea.spadaccini@gmail.com"

import logging
import StringIO

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp.xmpp_handlers import CommandHandler

from wordreference import JsonResult

HELP = """Hello. This is the WordReference.com XMPP bot.

I'm here to translate your words using the WordReference.com dictionaries.
To translate a word from a language to another, you have to send me a message
with two words. 

The first word is the dictionary that I should use, made by the union of the
source and destination language two-letters abbreviations. For example, to
translate from english to french use the dictionary "enfr". The second word is
the term to translate.

Example: translate "keys" from English to French.

    enfr keys

In addition to accept translating requests, I also understand these commands:
    /help               -> display this help message
    /abbreviations      -> display a list of abbreviations

For feedback, please write to andrea.spadaccini@gmail.com or file an issue at
http://code.google.com/p/wordreference-bot."""


class XMPPHandler(CommandHandler):
    DEFAULT_DISPLAY_ENTRIES, DEFAULT_DISPLAY_COMPOUNDS = 3, 1
    def text_message(self, message):
        try:
            # very basic hypothesis: the user enters two words. The first is the
            # dictionary and the second is the word to look up. Other words will be
            # ignored
            dictionary, word = message.body.split()[0:2]
            dictionary, word = dictionary.lower(), word.lower()

            logging.debug("Got word %s, dictionary %s" % (word, dictionary))
            res = self.build_answer_from_json_api(dictionary, word)

            message.reply(res.encode('utf8'))
        except ValueError, e:
            # Input error
            logging.error("Input error, message: %s" % message.body)
            message.reply("Input error. Please specify the dictionary and the word to look up (e.g.: enit hello for translating hello to italian")

        except Exception, e:
            import traceback
            logging.error("Error. %s" % (str(e)))
            logging.error(repr(traceback.format_stack()))
            message.reply("Sorry, there was an error: %s" % (str(e)))

    def help_command(self, message):
        message.reply(HELP)

    def build_answer_from_json_api(self, dictionary, word):
        logging.debug("About to get results")
        res = JsonResult(dictionary, word)
        logging.debug("Got results and parsed them.")
        tr_count = len(res.translations)
        comp_count = len(res.compounds)
        res_description = "Found %d translations and %d compound forms" % (tr_count, comp_count)
        logging.debug(res_description)

        buf = StringIO.StringIO()
        buf.write(res_description)
        buf.write('\n')

        if tr_count > 0:
            buf.write('\nTranslations:\n')
            for index, translation in enumerate(res.translations):
                if index == XMPPHandler.DEFAULT_DISPLAY_ENTRIES:
                    break
                buf.write(unicode(translation))
                buf.write('\n')

        if comp_count > 0:
            buf.write('\nCompound forms:\n')
            for index, compound in enumerate(res.compounds):
                if index == XMPPHandler.DEFAULT_DISPLAY_ENTRIES:
                    break
                buf.write(unicode(compound))
                buf.write('\n')

        if tr_count + comp_count > 0:
            buf.write('\nGo to http://wordreference.com/%s/%s for more.' % (dictionary, word))

        res = buf.getvalue()
        buf.close()
        logging.debug('Built output')
        return res


application = webapp.WSGIApplication([('/_ah/xmpp/message/chat/', XMPPHandler)], debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
